package de.hs.rm.UJAdapter.impl;

import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.management.Attribute;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularDataSupport;

import org.osgi.service.upnp.UPnPStateVariable;

import de.hs.rm.UJAdapter.util.ClassTypeUtil;

public class UJActionOpenTypeSetter extends UJAction {

	private OpenType attributeOpenType = null;
	private String attributeName = null;
	private static final String ARRAY_PREFIX = "_"; 
	private int arraySize = 0;
	
	
	public int getArraySize() {
		return arraySize;
	}

	public void setArraySize(int arraySize) {
		this.arraySize = arraySize;
	}

	public OpenType getAttributeOpenType() {
		return attributeOpenType;
	}

	public void setAttributeOpenType(OpenType attributeOpenType) {
		this.attributeOpenType = attributeOpenType;
	}

	public String getAttributeName() {
		return attributeName;
	}

	public void setAttributeName(String attributeName) {
		this.attributeName = attributeName;
	}
	
	@Override
	public Dictionary invoke(Dictionary args) throws Exception {
		
		//Dictionary returnValue = new Hashtable();
		
	//	Object[] params = {args.elements()};
		
	//	Object result = mBeanServerConnection.getAttribute(objName
	//			, attributeName);
	//	ArrayList<Object> oList = new ArrayList<Object>();
		
		Attribute attr = null;
		
		if (arraySize > 0)
		{
			Object[] attrObject= new Object[arraySize];
			for(int i = 0; i < arraySize; i++)
				attrObject[i] = createAttributeObject(args, ((ArrayType)attributeOpenType).getElementOpenType(), i);
			attr = new Attribute(attributeName, attrObject);			
		}
		else
		{
			Object attrObject = createAttributeObject(args, attributeOpenType, -1);
			attr = new Attribute(attributeName, attrObject);			
		}		
		
		mBeanServerConnection.setAttribute(objName
				, attr);
		return null;
	}
	
	private Object createAttributeObject(Dictionary args, OpenType openType, int index)
	{
		Object attrObject = null;
		String openTypeClassString = openType.toString();
		//recursively add simple type state variables from complex types
		switch(ClassTypeUtil.getOpenType(openTypeClassString))
		{ 
			case ClassTypeUtil.OPENTYPE_COMPOSITE:
				CompositeType cType = (CompositeType)openType;
				Set<String> cKeys = cType.keySet();
				Iterator<String> cIt = cKeys.iterator();
				String cNames[] = new String[cKeys.size()];
				Object cValues[] = new Object[cKeys.size()];
				String compTypeName = cType.getTypeName();
				if(compTypeName.contains("."))
					compTypeName = compTypeName.substring(compTypeName.lastIndexOf(".")+1);
				if(index != -1)
					compTypeName = index + "_" +compTypeName;
				
				int i = 0;
				while(cIt.hasNext())
				{
					String key = cIt.next();
					cNames[i] = key;
					cValues[i] = args.get(compTypeName + "." + key);
					i++;
				}
				CompositeData cOpenData;
				try {
					cOpenData = new CompositeDataSupport(cType, cNames, cValues);
					attrObject = cOpenData;
				} catch (OpenDataException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			break;
			
//			case ClassTypeUtil.OPENTYPE_ARRAY:
//				ArrayType aType = (ArrayType)openType;
//				Object[] = new Object
//				for (int i = 0; i < this.arraySize; i++)
//					createComplexData(aOpenData[i], oList);
//			break;
//				
//			case ClassTypeUtil.OPENTYPE_TABULAR:
//				TabularDataSupport tOpenData = 
//					(TabularDataSupport) openType;
//				tOpenData.keySet();
//				Set<Object> tKeys = tOpenData.keySet();
//				Iterator<Object> kIt = tKeys.iterator();
//				while(kIt.hasNext())
//				{
//					Object key = kIt.next();
//						createComplexData(tOpenData.get(key), oList);
//				}
//			break;
			
			case ClassTypeUtil.OPENTYPE_SIMPLE:
				attrObject = args.get(attributeName);
			break;
		}
		return attrObject;
	}
		
	
}
